﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace UnitySheet
{
    /// <summary>
    /// 对表格的操作：删除、拆分、合并等
    /// </summary>
    public class SheetOperator : MonoBehaviour
    {
        public delegate void SelectCell(Cell cell);
        public event SelectCell onSelectCell;
        public event SelectCell onDeselectCell;
        List<Cell> selectedCells = new List<Cell>();
        int minX = 0, minY = 0, maxX = 0, maxY = 0;
        public bool canMerge
        {
            get { return _CanMerge; }
            private set
            {
                _CanMerge = value;
                SheetManager.sheetManager.sheetUI.merge.interactable = value;
            }
        }
        bool _CanMerge = false;
        // Use this for initialization
        void Start()
        {
            SheetManager.sheetManager.onSelectOneSheet += OnSelectOneSheet;
            SheetManager.sheetManager.onDeselectSheet += OnDeselectOneSheet;
        }

        public Cell[] GetSelectedCells()
        {
            return selectedCells.ToArray();
        }

        public void OnSelectOneCell(Cell cell)
        {
            //方法存在问题
            SheetManager.sheetManager.OnSelectSheet(cell.mySheet);
            if (Input.GetKey(KeyCode.LeftShift)||Input.GetKey(KeyCode.RightShift))
            {
                selectedCells.Add(cell);
            }
            else
            {
                Cell[] cs = selectedCells.ToArray();
                selectedCells.Clear();
                selectedCells.Add(cell);
                for (int i = 0; i < cs.Length; i++)
                {
                    cs[i].Deselected();
                }
            }
            UpdateCorner();
            canMerge = CheckMerge();
            if (onSelectCell != null)
            {
                onSelectCell(cell);
            }
        }
        public void OnDeselectOneCell(Cell cell)
        {
            if (selectedCells.Contains(cell))
            {
                selectedCells.Remove(cell);
                if (selectedCells.Count > 0)
                {
                    UpdateCorner();
                    canMerge = CheckMerge();
                }
                else
                {
                    SheetManager.sheetManager.OnDeselectOneSheet(cell.mySheet);
                    canMerge = false;
                }
                if (onDeselectCell != null)
                {
                    onDeselectCell(cell);
                }
            }
        }

        void OnSelectOneSheet(Sheet sheet)
        {
            if (selectedCells.Count > 0 && selectedCells[0].mySheet != sheet)
            {
                selectedCells.Clear();
            }
        }

        void OnDeselectOneSheet(Sheet sheet)
        {
            int count = selectedCells.Count;
            for (int i = 0; i < count; i++)
            {
                selectedCells[0].Deselected();
            }
        }

        #region//添加
        public void AddRow()
        {
            SheetManager.sheetManager.selectedSheet.AddRow();
        }

        public void AddColumn()
        {
            SheetManager.sheetManager.selectedSheet.AddColumn();
        }
        #endregion

        #region//删除功能
        public void DeleteRowCells()
        {
            int count = selectedCells.Count;
            for (int i = 0; i < count; i++)
            {
                SheetManager.sheetManager.selectedSheet.DeleteRowCells(selectedCells[0]);
            }
        }
        public void DeleteColumnCells()
        {
            int count = selectedCells.Count;
            for (int i = 0; i < count; i++)
            {
                SheetManager.sheetManager.selectedSheet.DeleteColumnCells(selectedCells[0]);
            }
        }

        #endregion

        #region//拆分功能
        public void SpliteColumn()
        {
            int num;
            bool b = int.TryParse(SheetManager.sheetManager.sheetUI.columnNum.text, out num);
            if (!b)
            {
                SheetManager.SheetMessage("输入有误！");
            }
            else if (num > SheetManager.sheetManager.maxSpliteNum)
            {
                SheetManager.SheetMessage("一次最多只能拆分为" + SheetManager.sheetManager.maxSpliteNum + "个单元格！");
            }
            else
            {
                int count = selectedCells.Count;
                for (int i = 0; i < count; i++)
                {
                    SpliteColumn(selectedCells[0], int.Parse(SheetManager.sheetManager.sheetUI.columnNum.text));
                }
            }
        }
        public void SpliteRow()
        {
            int num;
            bool b = int.TryParse(SheetManager.sheetManager.sheetUI.rowNum.text, out num);
            if (!b)
            {
                SheetManager.SheetMessage("输入有误！");
            }
            else if (num > SheetManager.sheetManager.maxSpliteNum)
            {
                SheetManager.SheetMessage("一次最多只能拆分为" + SheetManager.sheetManager.maxSpliteNum + "个单元格！");
            }
            else
            {
                int count = selectedCells.Count;
                for (int i = 0; i < count; i++)
                {
                    SplitRow(selectedCells[0], int.Parse(SheetManager.sheetManager.sheetUI.rowNum.text));
                }
            }
        }

        /// <summary>
        /// 拆分单元格
        /// </summary>
        /// <param name="rowNum">行数</param>
        /// <param name="columnNum">列数</param>
        public void SplitCell(int rowNum, int columnNum)
        {
            if (selectedCells.Count == 1)
            {
                SplitRow(selectedCells[0], rowNum);
                SpliteColumn(selectedCells[0], columnNum);
            }
        }

        /// <summary>
        /// 拆分行-> —
        /// </summary>
        void SplitRow(Cell cell, int num)
        {
            if (num <= 1)
                return;
            List<List<AnchorPoint>> aps = new List<List<AnchorPoint>>();
            int cellLen = cell.cellHeight;

            if (cellLen % num == 0)//如果是约数
            {
                int space = cellLen / num;
                for (int x = 0; x < SheetManager.sheetManager.selectedSheet.xNum; x++)
                {
                    //aps.Add(SheetManager.sheetManager.sheet.anchors[x + space * (x + 1)]);
                    List<AnchorPoint> yaps = new List<AnchorPoint>();
                    for (int y = 1; y < num; y++)
                    {
                        yaps.Add(SheetManager.sheetManager.selectedSheet.anchors[x][cell.anchorPoints[0].y + space * y]);
                    }
                    aps.Add(yaps);
                }
            }
            else if (cellLen == 1)//如果长度为1的话，可以自由拆分
            {
                for (int x = 0; x < SheetManager.sheetManager.selectedSheet.xNum; x++)
                {
                    List<AnchorPoint> xaps = new List<AnchorPoint>();
                    for (int y = 1; y < num; y++)
                    {
                        Vector2 pos = SheetManager.sheetManager.selectedSheet.anchors[x][cell.anchorPoints[0].y].transform.position;
                        pos.y -= y * Mathf.Abs(cell.anchorPoints[2].transform.position.y - cell.anchorPoints[0].transform.position.y) / num;
                        AnchorPoint ap = SheetManager.sheetManager.selectedSheet.CreateOneAnchorPoint(x, cell.anchorPoints[0].y + y, pos);
                        xaps.Add(ap);
                    }
                    aps.Add(xaps);
                }
                SheetManager.sheetManager.selectedSheet.InsertRowAnchorPoints(aps, cell.anchorPoints[0].y);
            }
            else//既不是单元格长度的约数，单元格的长度又不为1，则发出错误提示
            {
                SheetManager.SheetMessage("必须为" + cellLen + "的约数！");
                return;
            }

            Cell[] newCells = new Cell[num];
            List<AnchorPoint> prevCellAps = cell.anchorPoints;
            SheetManager.sheetManager.selectedSheet.cells.Remove(cell.anchorPoints[0]);
            for (int i = 0; i < newCells.Length; i++)
            {
                AnchorPoint[] cellAPs = new AnchorPoint[4];
                if (i == 0)
                {
                    cellAPs[0] = prevCellAps[0];
                    cellAPs[1] = prevCellAps[1];
                    cellAPs[2] = aps[prevCellAps[0].x][0];
                    cellAPs[3] = aps[prevCellAps[1].x][0];
                }
                else if (i == newCells.Length - 1)
                {
                    cellAPs[0] = aps[prevCellAps[0].x][aps[prevCellAps[0].x].Count - 1];
                    cellAPs[1] = aps[prevCellAps[1].x][aps[prevCellAps[0].x].Count - 1];
                    cellAPs[2] = prevCellAps[2];
                    cellAPs[3] = prevCellAps[3];
                }
                else
                {
                    cellAPs[0] = aps[prevCellAps[0].x][i - 1];
                    cellAPs[1] = aps[prevCellAps[1].x][i - 1];
                    cellAPs[2] = aps[prevCellAps[2].x][i];
                    cellAPs[3] = aps[prevCellAps[3].x][i];
                }
                newCells[i] = SheetManager.sheetManager.selectedSheet.CreateOneCell(cellAPs);
            }
            SheetManager.sheetManager.selectedSheet.DestroyCell(cell);
        }

        /// <summary>
        /// 拆分列-> |
        /// </summary>
        /// <param name="cell">选择的单元格</param>
        /// <param name="num">拆分出的列数</param>
        void SpliteColumn(Cell cell, int num)
        {
            if (num <= 1)
                return;
            List<List<AnchorPoint>> aps = new List<List<AnchorPoint>>();
            int cellLen = cell.cellWidth;
            if (cellLen % num == 0)//如果是约数
            {
                int space = cellLen / num;
                for (int i = 0; i < num - 1; i++)
                {
                    aps.Add(SheetManager.sheetManager.selectedSheet.anchors[cell.anchorPoints[0].x + space * (i + 1)]);
                }
            }
            else if (cellLen == 1)//如果长度为1的话，可以自由拆分
            {
                for (int i = 0; i < num - 1; i++)
                {
                    List<AnchorPoint> caps = new List<AnchorPoint>();
                    int x = cell.anchorPoints[0].x + i + 1;
                    float xPos = cell.anchorPoints[0].transform.position.x + Mathf.Abs(cell.anchorPoints[1].transform.position.x - cell.anchorPoints[0].transform.position.x) / num * (i + 1);
                    for (int j = 0; j < SheetManager.sheetManager.selectedSheet.yNum; j++)
                    {
                        int y = j;
                        float yPos = SheetManager.sheetManager.selectedSheet.anchors[0][y].transform.position.y;
                        AnchorPoint ap = SheetManager.sheetManager.selectedSheet.CreateOneAnchorPoint(x, y, new Vector2(xPos, yPos));
                        caps.Add(ap);
                    }
                    aps.Add(caps);
                }
                SheetManager.sheetManager.selectedSheet.InsertColumnAnchorPoints(aps, cell.anchorPoints[0].x);
            }
            else//既不是单元格长度的约数，单元格的长度又不为1，则发出错误提示
            {
                SheetManager.SheetMessage("必须为" + cellLen + "的约数！");
                return;
            }

            Cell[] newCells = new Cell[num];
            List<AnchorPoint> prevCellAps = new List<AnchorPoint>();
            prevCellAps.AddRange(cell.anchorPoints);
            SheetManager.sheetManager.selectedSheet.cells.Remove(cell.anchorPoints[0]);
            for (int i = 0; i < newCells.Length; i++)
            {
                AnchorPoint[] cellAPs = new AnchorPoint[4];
                if (i == 0)
                {
                    cellAPs[0] = prevCellAps[0];
                    cellAPs[1] = aps[0][prevCellAps[1].y];
                    cellAPs[2] = prevCellAps[2];
                    cellAPs[3] = aps[0][prevCellAps[3].y];
                }
                else if (i == newCells.Length - 1)
                {
                    cellAPs[0] = aps[aps.Count - 1][prevCellAps[0].y];
                    cellAPs[1] = prevCellAps[1];
                    cellAPs[2] = aps[aps.Count - 1][prevCellAps[2].y];
                    cellAPs[3] = prevCellAps[3];
                }
                else
                {
                    cellAPs[0] = aps[i - 1][prevCellAps[0].y];
                    cellAPs[1] = aps[i][prevCellAps[1].y];
                    cellAPs[2] = aps[i - 1][prevCellAps[2].y];
                    cellAPs[3] = aps[i][prevCellAps[3].y];
                }
                newCells[i] = SheetManager.sheetManager.selectedSheet.CreateOneCell(cellAPs);
            }
            SheetManager.sheetManager.selectedSheet.DestroyCell(cell);
        }
        #endregion

        #region//合并功能
        /// <summary>
        /// 合并
        /// </summary>
        public void Merge()
        {
            AnchorPoint[] aps = new AnchorPoint[4];
            int num = selectedCells.Count;

            foreach (var item in selectedCells)
            {
                SheetManager.sheetManager.selectedSheet.cells.Remove(item.anchorPoints[0]);
                if (item.anchorPoints[0].x == minX && item.anchorPoints[0].y == minY)
                {
                    aps[0] = item.anchorPoints[0];
                }
                if (item.anchorPoints[1].x == maxX && item.anchorPoints[1].y == minY)
                {
                    aps[1] = item.anchorPoints[1];
                }
                if (item.anchorPoints[2].x == minX && item.anchorPoints[2].y == maxY)
                {
                    aps[2] = item.anchorPoints[2];
                }
                if (item.anchorPoints[3].x == maxX && item.anchorPoints[3].y == maxY)
                {
                    aps[3] = item.anchorPoints[3];
                }
            }
            Cell newCell = SheetManager.sheetManager.selectedSheet.CreateOneCell(aps);

            for (int i = 0; i < num; i++)
            {
                SheetManager.sheetManager.selectedSheet.DestroyCell(selectedCells[0]);
            }
            selectedCells.Clear();
        }


        /// <summary>
        /// 更新边界点
        /// </summary>
        void UpdateCorner()
        {
            int _minX = selectedCells[0].anchorPoints[0].x, _minY = selectedCells[0].anchorPoints[0].y, _maxX = selectedCells[0].anchorPoints[3].x, _maxY = selectedCells[0].anchorPoints[3].y;
            foreach (var item in selectedCells)
            {
                _minX = item.anchorPoints[0].x < _minX ? item.anchorPoints[0].x : _minX;
                _minY = item.anchorPoints[0].y < _minY ? item.anchorPoints[0].y : _minY;
                _maxX = item.anchorPoints[3].x > _maxX ? item.anchorPoints[3].x : _maxX;
                _maxY = item.anchorPoints[3].y > _maxY ? item.anchorPoints[3].y : _maxY;
            }
            maxX = _maxX;
            maxY = _maxY;
            minX = _minX;
            minY = _minY;
        }

        bool CheckMerge()
        {
            if (selectedCells.Count <= 1)
            {
                return false;
            }
            int anchorsCount = 0;
            foreach (var item in selectedCells)
            {
                anchorsCount += item.cellWidth * item.cellHeight;
            }

            int matrixNum = (maxX - minX) * (maxY - minY);
            return matrixNum == anchorsCount;
        }
        #endregion
    }
}
